package com.dd.logistics.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dd.logistics.entity.Inventory;
import com.dd.logistics.entity.InventoryHistory;
import com.dd.logistics.entity.SupplierProduct;
import com.dd.logistics.mapper.InventoryHistoryMapper;
import com.dd.logistics.mapper.InventoryMapper;
import com.dd.logistics.mapper.SupplierProductMapper;
import com.dd.logistics.service.InventoryService;
import com.dd.logistics.utils.OrderNumberGenerator;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class InventoryServiceImpl extends ServiceImpl<InventoryMapper, Inventory> implements InventoryService {
    
    @Autowired
    private InventoryHistoryMapper historyMapper;
    
    @Autowired
    private SupplierProductMapper supplierProductMapper;
    
    @Override
    public Page<Inventory> getPage(Integer current, Integer size, String productCode, String productName, String location) {
        log.info("分页查询库存，页码：{}，每页条数：{}，商品编码：{}，商品名称：{}，库位：{}", 
                current, size, productCode, productName, location);
        
        // 构建查询条件
        QueryWrapper<Inventory> wrapper = new QueryWrapper<>();
        if (StringUtils.hasText(productCode)) {
            wrapper.like("sp.product_code", productCode.trim());
        }
        if (StringUtils.hasText(productName)) {
            wrapper.like("sp.product_name", productName.trim());
        }
        if (StringUtils.hasText(location)) {
            wrapper.like("i.location", location.trim());
        }
        
        // 执行分页查询
        Page<Inventory> page = new Page<>(current, size);
        return baseMapper.selectPageWithInfo(page, wrapper);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateQuantity(String productCode, Integer adjustQuantity) {
        log.info("更新库存数量，商品编码：{}，调整数量：{}", productCode, adjustQuantity);
        
        try {
            // 查询商品信息
            QueryWrapper<SupplierProduct> productWrapper = new QueryWrapper<>();
            productWrapper.eq("product_code", productCode.trim());
            SupplierProduct product = supplierProductMapper.selectOne(productWrapper);
            
            if (product == null) {
                throw new RuntimeException("商品不存在");
            }
            
            // 查询库存记录
            QueryWrapper<Inventory> wrapper = new QueryWrapper<>();
            wrapper.eq("product_id", product.getId());
            Inventory inventory = baseMapper.selectOne(wrapper);
            
            // 如果是出库操作且库存记录不存在，抛出异常
            if (inventory == null && adjustQuantity < 0) {
                throw new RuntimeException("库存记录不存在，无法出库");
            }
            
            // 如果是入库操作且库存记录不存在，创建新记录
            if (inventory == null && adjustQuantity > 0) {
                inventory = new Inventory();
                inventory.setProductId(product.getId());
                inventory.setSupplierId(product.getSupplierId());
                inventory.setQuantity(0);
                inventory.setWarningThreshold(0);
                this.save(inventory);
                log.info("创建新的库存记录，商品编码：{}，商品ID：{}", productCode, product.getId());
            }
            
            // 检查库存是否足够（出库时）
            if (adjustQuantity < 0 && inventory.getQuantity() + adjustQuantity < 0) {
                throw new RuntimeException("库存不足，当前库存：" + inventory.getQuantity() + 
                    "，需要出库：" + Math.abs(adjustQuantity));
            }
            
            // 更新库存
            inventory.setQuantity(inventory.getQuantity() + adjustQuantity);
            boolean success = this.updateById(inventory);
            
            if (success) {
                // 记录历史
                InventoryHistory history = new InventoryHistory();
                history.setInventoryId(inventory.getId());
                history.setType(adjustQuantity > 0 ? "入库" : "出库");
                history.setQuantity(adjustQuantity);
                history.setOrderNumber(OrderNumberGenerator.generateInventoryHistoryNumber());
                historyMapper.insert(history);
                
                log.info("更新库存成功，商品编码：{}，原库存：{}，调整数量：{}，新库存：{}", 
                        productCode, inventory.getQuantity() - adjustQuantity, adjustQuantity, inventory.getQuantity());
                
                // 检查是否需要发出库存预警
                if (inventory.getQuantity() <= inventory.getWarningThreshold()) {
                    log.warn("库存预警：商品编码：{}，当前库存：{}，预警阈值：{}", 
                            productCode, inventory.getQuantity(), inventory.getWarningThreshold());
                }
            }
            
            return success;
        } catch (Exception e) {
            log.error("更新库存异常，商品编码：{}，调整数量：{}，异常：{}", 
                    productCode, adjustQuantity, e.getMessage());
            throw new RuntimeException("更新库存失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateInfo(Long id, String location, Integer warningThreshold) {
        log.info("更新库存信息，ID：{}，库位：{}，预警阈值：{}", id, location, warningThreshold);
        
        try {
            Inventory inventory = this.getById(id);
            if (inventory == null) {
                throw new RuntimeException("库存记录不存在");
            }
            
            inventory.setLocation(location);
            inventory.setWarningThreshold(warningThreshold);
            
            boolean success = this.updateById(inventory);
            if (success) {
                log.info("更新库存信息成功，ID：{}", id);
                
                // 检查是否需要发出库存预警
                if (inventory.getQuantity() <= warningThreshold) {
                    log.warn("库存预警：商品编码：{}，当前库存：{}，预警阈值：{}", 
                            inventory.getProductCode(), inventory.getQuantity(), warningThreshold);
                }
            }
            
            return success;
        } catch (Exception e) {
            log.error("更新库存信息异常，ID：{}，异常：{}", id, e.getMessage());
            throw new RuntimeException("更新库存信息失败：" + e.getMessage());
        }
    }
    
    @Override
    public List<InventoryHistory> getHistory(String productCode, String startDate, String endDate) {
        log.info("查询库存历史记录，商品编码：{}，开始日期：{}，结束日期：{}", 
                productCode, startDate, endDate);
        
        return historyMapper.selectHistoryList(productCode, startDate, endDate);
    }
    
    @Override
    public Map<String, Integer> getStats() {
        log.info("获取库存统计信息");
        
        List<Inventory> list = this.list();
        
        int totalProducts = list.size();
        int lowStockCount = 0;
        int zeroStockCount = 0;
        
        for (Inventory inventory : list) {
            if (inventory.getQuantity() == 0) {
                zeroStockCount++;
            } else if (inventory.getQuantity() <= inventory.getWarningThreshold()) {
                lowStockCount++;
            }
        }
        
        Map<String, Integer> stats = new HashMap<>();
        stats.put("totalProducts", totalProducts);
        stats.put("lowStockCount", lowStockCount);
        stats.put("zeroStockCount", zeroStockCount);
        
        return stats;
    }
    
    @Override
    public List<Inventory> getList() {
        return baseMapper.selectListWithInfo(new QueryWrapper<>());
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addInventory(Inventory inventory) {
        log.info("新增库存，商品ID：{}，数量：{}，库位：{}", 
                inventory.getProductId(), inventory.getQuantity(), inventory.getLocation());
        
        try {
            // 检查商品是否存在
            SupplierProduct product = supplierProductMapper.selectById(inventory.getProductId());
            if (product == null) {
                throw new RuntimeException("商品不存在");
            }
            
            // 检查是否已存在库存记录
            QueryWrapper<Inventory> wrapper = new QueryWrapper<>();
            wrapper.eq("product_id", inventory.getProductId());
            if (baseMapper.selectCount(wrapper) > 0) {
                throw new RuntimeException("该商品已存在库存记录");
            }
            
            boolean success = this.save(inventory);
            if (success) {
                log.info("新增库存成功，ID：{}", inventory.getId());
                
                // 如果初始库存大于0，记录入库历史
                if (inventory.getQuantity() > 0) {
                    InventoryHistory history = new InventoryHistory();
                    history.setInventoryId(inventory.getId());
                    history.setType("入库");
                    history.setQuantity(inventory.getQuantity());
                    history.setOrderNumber(OrderNumberGenerator.generateInventoryHistoryNumber());
                    historyMapper.insert(history);
                }
            }
            
            return success;
        } catch (Exception e) {
            log.error("新增库存异常，商品ID：{}，异常：{}", inventory.getProductId(), e.getMessage());
            throw new RuntimeException("新增库存失败：" + e.getMessage());
        }
    }
    
    @Override
    public boolean checkStock(Long productId, Integer quantity) {
        if (productId == null || quantity == null) {
            return false;
        }
        
        QueryWrapper<Inventory> wrapper = new QueryWrapper<>();
        wrapper.eq("product_id", productId);
        Inventory inventory = this.getOne(wrapper);
        
        return inventory != null && inventory.getQuantity() >= quantity;
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateQuantityByProductId(Long productId, Integer adjustQuantity) {
        log.info("根据商品ID更新库存，商品ID：{}，调整数量：{}", productId, adjustQuantity);
        
        try {
            // 查询商品信息
            SupplierProduct product = supplierProductMapper.selectById(productId);
            if (product == null) {
                throw new RuntimeException("商品不存在");
            }
            
            // 查询库存记录
            QueryWrapper<Inventory> wrapper = new QueryWrapper<>();
            wrapper.eq("product_id", productId);
            Inventory inventory = baseMapper.selectOne(wrapper);
            
            if (inventory == null) {
                throw new RuntimeException("库存记录不存在");
            }
            
            // 检查库存是否足够（出库时）
            if (adjustQuantity < 0 && inventory.getQuantity() + adjustQuantity < 0) {
                throw new RuntimeException("库存不足，当前库存：" + inventory.getQuantity() + 
                    "，需要出库：" + Math.abs(adjustQuantity));
            }
            
            // 更新库存
            inventory.setQuantity(inventory.getQuantity() + adjustQuantity);
            boolean success = this.updateById(inventory);
            
            if (success) {
                // 记录历史
                InventoryHistory history = new InventoryHistory();
                history.setInventoryId(inventory.getId());
                history.setType(adjustQuantity > 0 ? "入库" : "出库");
                history.setQuantity(adjustQuantity);
                history.setOrderNumber(OrderNumberGenerator.generateInventoryHistoryNumber());
                historyMapper.insert(history);
                
                log.info("更新库存成功，商品ID：{}，原库存：{}，调整数量：{}，新库存：{}", 
                        productId, inventory.getQuantity() - adjustQuantity, adjustQuantity, inventory.getQuantity());
                
                // 检查是否需要发出库存预警
                if (inventory.getQuantity() <= inventory.getWarningThreshold()) {
                    log.warn("库存预警：商品ID：{}，当前库存：{}，预警阈值：{}", 
                            productId, inventory.getQuantity(), inventory.getWarningThreshold());
                }
            }
            
            return success;
        } catch (Exception e) {
            log.error("更新库存异常，商品ID：{}，调整数量：{}，异常：{}", 
                    productId, adjustQuantity, e.getMessage());
            throw new RuntimeException("更新库存失败：" + e.getMessage());
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteInventory(Long id) {
        // 查询库存是否存在
        Inventory inventory = this.getById(id);
        if (inventory == null) {
            throw new RuntimeException("库存记录不存在");
        }
        
        try {
            // 删除相关的历史记录
            QueryWrapper<InventoryHistory> wrapper = new QueryWrapper<>();
            wrapper.eq("inventory_id", id);
            historyMapper.delete(wrapper);
            
            // 删除库存记录
            return this.removeById(id);
        } catch (Exception e) {
            log.error("删除库存失败，ID：{}，异常：{}", id, e.getMessage());
            throw new RuntimeException("删除库存失败：" + e.getMessage());
        }
    }
} 